/* Packages */
package edu.gatech.team404.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import edu.gatech.team404.Account;
import edu.gatech.team404.AccountType;
import edu.gatech.team404.Lab;
import edu.gatech.team404.Team;
import edu.gatech.team404.TeamAssignment;
import edu.gatech.team404.dal.CourseDAL;
import edu.gatech.team404.dal.LabDAL;
import edu.gatech.team404.dal.TeamDAL;
import edu.gatech.team404.tool.Log;
import edu.gatech.team404.tool.Scheduler;
import edu.gatech.team404.tool.StatusCode;
/**
 * Servlet implementation class LabServlet
 * @author Brendan Cecere
 * @version 1.0
 */
@WebServlet("/LabServlet")
public class LabServlet extends HttpServlet {

	/** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws NumberFormatException if a number format exception occurs
     * @throws IOException if an I/O error occurs
     */
	protected void processRequest(HttpServletRequest request, 
									HttpServletResponse response)
									throws IOException, NumberFormatException {

		response.setContentType("text/html;charset=UTF-8");
        final PrintWriter out = response.getWriter();
        final LabDAL dal = new LabDAL();
        final HttpSession session = request.getSession(true);
        final String statusTag = "labCreationStatus";
        final String courseName = request.getParameter("courseName");
        
        try {
        	
            final String name = request.getParameter("name");
            final Date startDate = 
            	Scheduler.convertToDate(request.getParameter("startDate"));
            final Date endDate = Scheduler.convertToDate(request.getParameter("endDate"));
            final String assignment = request.getParameter("teamAssignment");
            final String size = request.getParameter("teamSize");
            
            TeamAssignment teamAssignment= TeamAssignment.UNKNOWN;
            int teamSize = 1;
            
            boolean isValid = true;
            
            //Validate data
            if (courseName.isEmpty() ||
            	name.isEmpty() ||
            	assignment.isEmpty()) {
            	isValid = false;
            }
            
            if (startDate == null ||
            	endDate == null) {
            	isValid = false;
            }
            
            //Team Assignment
            if(assignment.equalsIgnoreCase("Individual")){
            	teamAssignment = TeamAssignment.INDIVIDUAL;
            }
            else if(assignment.equalsIgnoreCase("Random")){
            	teamAssignment = TeamAssignment.RANDOM;
            }
            else if(assignment.equalsIgnoreCase("Self Select")){
            	teamAssignment = TeamAssignment.SELF_SELECT;
            }
            else {
            	isValid = false;
            }
            
            //team size
            try {
            	teamSize = Integer.parseInt(size);
            }
            catch (NumberFormatException e) {
            	Log.error("LabServlet", e);
            	isValid = false;
            }
            
            //Create lab
            if (isValid) {
            	boolean ret = true;
            	
            	final Lab lab = 
            		new Lab (courseName, null, name, startDate, endDate, teamAssignment, teamSize);
            	ret = dal.createLab(lab);
            	
            	if (ret) {
            		//Create random assignment
            		if (teamAssignment == TeamAssignment.RANDOM) {
            			final CourseDAL cDal = new CourseDAL ();
            			final TeamDAL tDal = new TeamDAL ();
            			final List<Account> students = cDal.getStudents(courseName);
            			final int numTeams = (int) Math.ceil(students.size() / (double) teamSize);
            			final int averageSize = (int) Math.ceil(students.size() / (double) numTeams);
            			
            			for (int i = 0; i < numTeams; i++) {
            				Team team = new Team(lab.getId(), null, "Team " + (i + 1));
            				
            				for (int j = 0; j < averageSize; j++) {
            					int index = (int) (Math.random() * students.size());
            					team.addMember(students.remove(index));

            					if(students.size() == 0) {
            						break;
            					}
            				}
            				
            				ret &= tDal.createTeam(team);

            				//sanity check
            				if(students.size() == 0) {
        						break;
        					}
            			}
            		}
            	}
            	
               if(ret) {
 	        	   session.setAttribute(statusTag, StatusCode.LAB_CREATE_SUCCESS);
 	           }
 	           else{
 	        	   session.setAttribute(statusTag, StatusCode.LAB_CREATE_FAIL);
 	           }
            }
            else {
            	session.setAttribute(statusTag, StatusCode.LAB_CREATE_INVALID_DATA);
            }
        }
        finally {
        	session.setAttribute("feed", StatusCode.CREATE.toString());
        	response.sendRedirect("lab.jsp?course=" 
        			+ URLEncoder.encode(courseName, "UTF-8"));
            out.close();
            dal.close();
        }
	}
	
	/** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws NumberFormatException if a number format exception occurs
     * @throws IOException if an I/O error occurs
     */
	@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, NumberFormatException {
        processRequest(request, response);
    } 

	/** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws NumberFormatException if a number format exception occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, NumberFormatException {
        processRequest(request, response);
    }


}
